/**
 * @Author: YangYun
 * @Date: 2020/7/27 15:49
 */
package pay

import (
	"context"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"git.900sui.cn/kc/kcgin/logs"
	"git.900sui.cn/kc/rpcinterface/client/market"
	"git.900sui.cn/kc/rpcinterface/interface/common"
	market2 "git.900sui.cn/kc/rpcinterface/interface/market"
	"sort"
	"strconv"
	"strings"
	"time"

	"git.900sui.cn/kc/base/common/functions"
	"git.900sui.cn/kc/base/common/toolLib"
	"git.900sui.cn/kc/base/utils"
	"git.900sui.cn/kc/kcgin"
	"git.900sui.cn/kc/rpcPay/common/lib"
	"git.900sui.cn/kc/rpcPay/common/models"
	_const "git.900sui.cn/kc/rpcPay/lang/const"
	bus2 "git.900sui.cn/kc/rpcinterface/client/bus"
	pay3 "git.900sui.cn/kc/rpcinterface/client/task/pay"
	"git.900sui.cn/kc/rpcinterface/interface/bus"
	"git.900sui.cn/kc/rpcinterface/interface/order"
	pay2 "git.900sui.cn/kc/rpcinterface/interface/pay"
	"github.com/shopspring/decimal"
	"github.com/tidwall/gjson"
)

type sandPay struct {
}

func (s *sandPay) PayQr(payInfo *pay2.PayInfo) (string, error) {
	realAmount, _ := decimal.NewFromString(payInfo.RealAmount)
	return lib.Sandpay.QrCode(payInfo.OrderSn, realAmount, "商品标题信息", "商品内容", payInfo.FormUrl)
}

func (s *sandPay) PayH5(payInfo *pay2.PayInfo) (string, error) {
	realAmount, _ := decimal.NewFromString(payInfo.RealAmount)
	return lib.Sandpay.H5(payInfo.OrderSn, realAmount, "订单支付", "订单支付", payInfo.FormUrl)
}

func (s *sandPay) PayH5New(payInfo *pay2.PayInfo, p *pay2.PayH5) (err error) {
	realAmount, _ := decimal.NewFromString(payInfo.RealAmount)
	return lib.Sandpay.H5New(payInfo.OrderSn, realAmount, "订单支付", "订单支付", payInfo.FormUrl, p)
}

func (s *sandPay) PayWxApp(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	realAmount, _ := decimal.NewFromString(payInfo.RealAmount)
	return lib.Sandpay.WxApp(payInfo.OrderSn, realAmount, "订单支付", "订单支付", payInfo.FormUrl, payInfo.AppId, payInfo.OpenId)
}

// 微信公众号支付
func (s *sandPay) PayWxOfficial(info *pay2.PayInfo) (*gjson.Result, error) {
	return nil, nil
}

func (s *sandPay) PayApp(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	orderTime := time.Now().Unix()
	expireTime := orderTime + (60 * 15)
	resMap := map[string]interface{}{
		"expire_time":  expireTime,
		"product_code": "00002021",
		"clear_cycle":  0,
		"orderSn":      payInfo.OrderSn,
		"orderTime":    orderTime,
		"title":        kcgin.AppConfig.String("Pay.title"),
		"notifyUrl":    kcgin.AppConfig.String("sandpay.notifyUrl"),
		"formUrl":      payInfo.FormUrl,
		"amount":       payInfo.RealAmount,
		"agentId":      kcgin.AppConfig.String("sandpay.mid"),
		// "agentKey":      kcgin.AppConfig.String("sandpay.privateKey"),
		"merKey": kcgin.AppConfig.String("sandpay.merKey"),
		// "sign":          kcgin.AppConfig.String("sandpay.sign"),
		"version":       payInfo.Version,
		"create_ip":     payInfo.CreateIP,
		"store_id":      payInfo.StoreID,
		"pay_extra":     payInfo.PayExtra,
		"accsplit_flag": payInfo.AccsplitFlag,
		"sign_type":     payInfo.SignType,
	}
	marshal, _ := json.Marshal(resMap)
	result := gjson.ParseBytes(marshal)
	return &result, nil
}

func (s *sandPay) PayAppSign(payInfo *pay2.PayInfo) (string, error) {
	orderTime := time.Now()
	orderTimeString := orderTime.Format("20060102150405")
	resMap := map[string]interface{}{
		"mer_no":       kcgin.AppConfig.String("sandpay.mid"),
		"mer_key":      kcgin.AppConfig.String("sandpay.merKey"),
		"mer_order_no": payInfo.OrderSn,
		"create_time":  orderTimeString,
		"order_amt":    payInfo.RealAmount,
		"notify_url":   kcgin.AppConfig.String("sandpay.notifyUrl"),
		// "return_url":    payInfo.FormUrl,
		"version":       payInfo.Version,
		"create_ip":     payInfo.CreateIP,
		"store_id":      payInfo.StoreID,
		"pay_extra":     payInfo.PayExtra,
		"accsplit_flag": payInfo.AccsplitFlag,
		"sign_type":     payInfo.SignType,
	}

	keys := []string{
		"mer_no",
		"mer_key",
		"mer_order_no",
		"create_time",
		"order_amt",
		"notify_url",
		// "return_url",
		"version",
		"create_ip",
		"store_id",
		"pay_extra",
		"accsplit_flag",
		"sign_type",
	}

	sort.Strings(keys)
	strs := ""
	for _, v := range keys {
		strs += v + "=" + resMap[v].(string) + "&"
	}

	strs += "key=" + kcgin.AppConfig.String("sandpay.sign")
	md5Ctx := md5.New()
	md5Ctx.Write([]byte(strs))
	md5Str := md5Ctx.Sum(nil)

	return strings.ToUpper(hex.EncodeToString(md5Str)), nil
}

func (s *sandPay) Notify(data string) (*pay2.PayNotify, error) {
	gData, err := lib.Sandpay.Notify(data)
	if err != nil {
		return nil, err
	}
	if gData.Get("orderStatus").String() != "1" {
		return nil, toolLib.CreateKcErr(_const.PAY_ERROR)
	}
	fen := decimal.NewFromInt(100)
	fee := decimal.NewFromInt(0)
	gData.ForEach(func(key, value gjson.Result) bool {
		if strings.HasSuffix(key.String(), "Fee") {
			fee = fee.Add(decimal.NewFromInt(value.Int()))
		}
		return true
	})

	payTime := functions.StrtoTime(gData.Get("payTime").String(), "20060102150405")
	return &pay2.PayNotify{
		OrderSn:    gData.Get("orderCode").String(),
		PayTime:    payTime,
		PayAmount:  decimal.NewFromInt(gData.Get("totalAmount").Int()).Div(fen).String(),
		PayFee:     fee.Div(fen).String(),
		PaySn:      gData.Get("tradeNo").String(),
		PayStatus:  pay2.PAY_Suc,
		PayChannel: order.PAY_CHANNEL_sand,
		PayType:    order.PAY_TYPE_YUAN,
	}, nil
}

//异步回调响应
func (s *sandPay) NotifyResponse(ctx context.Context, args *pay2.ArgsNotify) (*pay2.ReplyNotifyResponse, error) {
	return nil, nil
}

// 获取支付成功后金额处理
func (s *sandPay) PayFund(notify *pay2.PayNotify, bill *order.ReplyGetOrderSplitBill) []bus.FundRecordItem {
	return []bus.FundRecordItem{
		{
			OrderSn:  notify.OrderSn,
			Amount:   notify.PayAmount,
			FundType: bus.FUND_TYPE_pay_in,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   notify.PayFee,
			FundType: bus.FUND_TYPE_bankfee_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.InsureAmount).String(),
			FundType: bus.FUND_TYPE_insurance_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.RenewInsureAmount).String(),
			FundType: bus.FUND_TYPE_reinsurance_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.PlatformAmount).String(),
			FundType: bus.FUND_TYPE_plat_out,
		},
	}
}

// 获取清分金额
func (s *sandPay) GetFundAmount(notify *pay2.PayNotify, bill *order.ReplyGetOrderSplitBill) string {
	fee, _ := decimal.NewFromString(notify.PayFee)
	return decimal.NewFromFloat(bill.BusAmount).Sub(fee).String()
}

// 获取支付方式
func (s *sandPay) GetType() int {
	return order.PAY_CHANNEL_sand
}

/**
 * 资金清分【商家】
 * @return void
 */
func (s *sandPay) AgentChannel(busClearingModel *models.BusClearingModel, list map[string]interface{}) (id int, err error) {
	busClearingSandpayModel := new(models.BusClearingSandpayModel).Init(busClearingModel.Model.GetOrmer())
	res := busClearingSandpayModel.FindByBusIdAndStatus(list[busClearingModel.Field.F_bus_id], pay2.CLEAR_STATUS_none)
	if len(res) > 0 {
		// 清分金额单次汇总
		upRes, err := busClearingSandpayModel.UpdateByIdAndStatus(res[busClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_none, map[string]interface{}{
			busClearingSandpayModel.Field.F_amount:            []interface{}{"inc", list[busClearingModel.Field.F_amount]},
			busClearingSandpayModel.Field.F_depository_amount: []interface{}{"inc", list[busClearingModel.Field.F_depository_amount]},
			busClearingSandpayModel.Field.F_usable_amount:     []interface{}{"inc", list[busClearingModel.Field.F_usable_amount]},
		})
		if err != nil || upRes != 1 {
			return 0, toolLib.CreateKcErr(_const.PAY_ERROR)
		}
		id, err = strconv.Atoi(res[busClearingSandpayModel.Field.F_id].(string))
		if err != nil {
			return 0, toolLib.CreateKcErr(_const.PAY_ERROR)
		}
	} else {
		times := time.Now().Local().Unix()
		id = busClearingSandpayModel.Insert(map[string]interface{}{
			busClearingSandpayModel.Field.F_bus_id:            list[busClearingModel.Field.F_bus_id],
			busClearingSandpayModel.Field.F_amount:            list[busClearingModel.Field.F_amount],
			busClearingSandpayModel.Field.F_depository_amount: list[busClearingModel.Field.F_depository_amount],
			busClearingSandpayModel.Field.F_usable_amount:     list[busClearingModel.Field.F_usable_amount],
			busClearingSandpayModel.Field.F_create_time:       times,
		})
		if id == 0 {
			return 0, toolLib.CreateKcErr(_const.PAY_ERROR)
		}
	}
	return id, nil
}

/**
 * 资金清分【平台】
 * @return void
 */
func (s *sandPay) AgentChannelPlat(platClearingModel *models.PlatformClearingModel, list map[string]interface{}) (id int, err error) {
	platClearingSandpayModel := new(models.PlatformClearingSandpayModel).Init(platClearingModel.Model.GetOrmer())
	res := platClearingSandpayModel.GetByStatus(pay2.CLEAR_STATUS_none)
	if len(res) > 0 {
		id, _ = strconv.Atoi(res[platClearingSandpayModel.Field.F_id].(string))
		_, err = platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_none, map[string]interface{}{
			platClearingSandpayModel.Field.F_amount: []interface{}{"inc", list[platClearingModel.Field.F_amount]},
		})
		if err != nil {
			err = errors.New("dberror for update platClearSandpayModel err:" + err.Error())
			return
		}
	} else {
		times := time.Now().Local().Unix()
		id = platClearingSandpayModel.Insert(map[string]interface{}{
			platClearingSandpayModel.Field.F_amount:      list[platClearingModel.Field.F_amount],
			platClearingSandpayModel.Field.F_create_time: times,
		})
		if id == 0 {
			err = errors.New("dberror for insert platClearSandpayModel err")
			return
		}
	}
	return
}

/**
 * 资金清分【保险】
 * @return void
 */
func (s *sandPay) AgentChannelInsure(insureClearingModel *models.InsureClearingModel, list map[string]interface{}) (id int, err error) {
	insureClearingSandpayModel := new(models.InsureClearingSandpayModel).Init(insureClearingModel.Model.GetOrmer())
	res := insureClearingSandpayModel.FindByInsureIdAndStatus(list[insureClearingModel.Field.F_insure_id], pay2.CLEAR_STATUS_none)
	if len(res) > 0 {
		id, _ = strconv.Atoi(res[insureClearingSandpayModel.Field.F_id].(string))
		_, err = insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_none, map[string]interface{}{
			insureClearingSandpayModel.Field.F_amount: []interface{}{"inc", list[insureClearingModel.Field.F_amount]},
		})
		if err != nil {
			err = errors.New("dberror for update insureClearingSandpayModel err:" + err.Error())
			return
		}
	} else {
		times := time.Now().Local().Unix()
		id = insureClearingSandpayModel.Insert(map[string]interface{}{
			insureClearingSandpayModel.Field.F_insure_id:   list[insureClearingModel.Field.F_insure_id],
			insureClearingSandpayModel.Field.F_amount:      list[insureClearingModel.Field.F_amount],
			insureClearingSandpayModel.Field.F_create_time: times,
		})
		if id == 0 {
			err = errors.New("dberror for insert insureClearingSandpayModel err")
			return
		}
	}
	return
}

/**
 * 资金清分【续保保险】
 * @return void
 */
func (s *sandPay) AgentChannelRenewInsure(renewInsureClearingModel *models.RenewInsureClearingModel, list map[string]interface{}) (id int, err error) {
	renewInsureClearingSandpayModel := new(models.RenewInsureClearingSandpayModel).Init(renewInsureClearingModel.Model.GetOrmer())
	res := renewInsureClearingSandpayModel.FindByInsureIdAndStatus(list[renewInsureClearingModel.Field.F_renew_insure_id], pay2.CLEAR_STATUS_none)
	if len(res) > 0 {
		id, _ = strconv.Atoi(res[renewInsureClearingSandpayModel.Field.F_id].(string))
		_, err = renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_none, map[string]interface{}{
			renewInsureClearingSandpayModel.Field.F_amount: []interface{}{"inc", list[renewInsureClearingModel.Field.F_amount]},
		})
		if err != nil {
			err = errors.New("dberror for update renewInsureClearingSandpayModel err:" + err.Error())
			return
		}
	} else {
		times := time.Now().Local().Unix()
		id = renewInsureClearingSandpayModel.Insert(map[string]interface{}{
			renewInsureClearingSandpayModel.Field.F_renew_insure_id: list[renewInsureClearingModel.Field.F_renew_insure_id],
			renewInsureClearingSandpayModel.Field.F_amount:          list[renewInsureClearingModel.Field.F_amount],
			renewInsureClearingSandpayModel.Field.F_create_time:     times,
		})
		if id == 0 {
			err = errors.New("dberror for insert renewInsureClearingSandpayModel err")
			return
		}
	}
	return
}

/**
 * 杉德代付资金【商户】
 * @return void
 */
func (s *sandPay) FundAgent(ctx context.Context) (rest bool) {
	rest = true
	//如果是节假日，则不进行代付
	if !s.checkHolidayPayment() {
		logs.Info("节假日不代付")
		return
	}
	//实例化清分表
	//杉德代付表
	busClearingSandpayModel := new(models.BusClearingSandpayModel).Init()
	//商户清分表
	busClearingModel := new(models.BusClearingModel).Init(busClearingSandpayModel.Model.GetOrmer())
	//清分成功关联表
	busClearingFundRealationModel := new(models.BusClearingFundRealationModel).Init(busClearingSandpayModel.Model.GetOrmer())
	//定义商户资金存管账户信息
	replyDeposSandInfos := []bus.ReplyDeposSandInfo{}
	depos := new(bus2.Depos).Init()
	reply := false
	rpcFund := new(bus2.Fund).Init()
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	taskPay := new(pay3.Pay).Init()
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForMerchant"))
	for true {
		//获取待代付数据
		lists := busClearingSandpayModel.GetListsByStatus(pay2.CLEAR_STATUS_none, start, linCount)
		listsLen := len(lists)
		//如果没有待代付数据，则直接跳出
		if listsLen == 0 {
			logs.Info("没有需要代付的数据")
			break
		}
		busIds := functions.ArrayValue2Array(busClearingSandpayModel.Field.F_bus_id, lists)
		//获取商户资金存管账户信息
		if err := depos.GetDeposSandInfos(ctx, &busIds, &replyDeposSandInfos); err != nil {
			paymentLog.Printf("获取商户资金存管账户信息失败,err:%v", err)
			return
		}
		//映射待代付商户对应其资金存管账户信息
		res := map[int]bus.ReplyDeposSandInfo{}
		if len(replyDeposSandInfos) > 0 {
			for _, replyDeposSandInfo := range replyDeposSandInfos {
				res[replyDeposSandInfo.BusId] = replyDeposSandInfo
			}
		}
		for _, list := range lists {
			busId, _ := strconv.Atoi(list[busClearingSandpayModel.Field.F_bus_id].(string))
			id, _ := strconv.Atoi(list[busClearingSandpayModel.Field.F_id].(string))
			//获取商户账户信息
			sandInfo, ok := res[busId]
			if !ok {
				paymentLog.Printf("该商户资金存管账户信息未找到,bus_id:%v", busId)
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(list[busClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_none, map[string]interface{}{
					busClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					busClearingSandpayModel.Field.F_error_msg: "该商户资金存管账户信息未找到",
				}); err != nil {
					paymentLog.Printf("updatedb err,bus_id:%v,clearingSandpayId:%v", busId, id)
					continue
				}
				continue
			}
			//\\获取商户账户信息
			//定义代付订单号
			orderSn := "PM" + strconv.FormatInt(lib.Worker.GetId(), 10)
			//获取总金额
			amount, _ := decimal.NewFromString(list[busClearingSandpayModel.Field.F_amount].(string))
			//获取计算手续费
			fee, err := lib.Sandpay.AgentFee(orderSn, amount, sandInfo.AcctNo)
			if err != nil {
				paymentLog.Printf("计算代付手续费错误:err:%v", err)
				continue
			}
			amountFee := fee.GetFee()
			usableAmount, _ := decimal.NewFromString(list[busClearingSandpayModel.Field.F_usable_amount].(string))
			//如果代付手续费大于总金额则跳出，继续
			if amount.Cmp(amountFee) < 0 {
				paymentLog.Printf("手续费大于代付金额， 手续费：%v, 代付金额：%v", busId, id)
			}
			//如果代付金额扣除代付手续费小于可用总金额则跳出，继续 暂时屏蔽待商榷，在很多天只有一笔订单的情况下，出现这笔订单一直不能代付
			//if amount.Sub(amountFee).Cmp(usableAmount) < 0 {
			//	continue
			//}
			fundAmount := amount.Sub(amountFee)
			usableAmount = usableAmount.Sub(amountFee)
			//手续费二次计算
			orderSn2 := "PF" + strconv.FormatInt(lib.Worker.GetId(), 10)
			fee, err = lib.Sandpay.AgentFee(orderSn2, fundAmount, sandInfo.AcctNo)
			if err != nil {
				paymentLog.Printf("计算二次手续费错误:err:%v", err)
				continue
			}
			amountFee2 := fee.GetFee()
			//如果两次计算的手续费不一致
			if amountFee.Cmp(amountFee2) != 0 {
				//手续费有变动，手动处理
				paymentLog.Printf("两次计算手续费计算不一致,amount1:%v,amount2:%v", amountFee, amountFee2)
				continue
			}
			if _, err := busClearingSandpayModel.UpdateAgent(id, pay2.CLEAR_STATUS_none, amount.String(), map[string]interface{}{
				busClearingSandpayModel.Field.F_status:         pay2.CLEAR_STATUS_ing,
				busClearingSandpayModel.Field.F_card_name:      sandInfo.AcctName,
				busClearingSandpayModel.Field.F_card_no:        sandInfo.AcctNo,
				busClearingSandpayModel.Field.F_card_bank_name: sandInfo.BankName,
				busClearingSandpayModel.Field.F_card_bank_no:   sandInfo.BankNo,
			}); err != nil {
				paymentLog.Printf("updatedb for sandpay ing status err:id:%v,err:%v", id, err)
				continue
			}
			orderSn = "PX" + strconv.FormatInt(lib.Worker.GetId(), 10)
			//执行代付
			result, err := lib.Sandpay.AgentPay(orderSn, fundAmount, sandInfo.AcctNo, sandInfo.AcctName, sandInfo.BankName, sandInfo.BankNo)
			if err != nil {
				paymentLog.Printf("执行杉德代付操作失败:id:%v,err:%v", id, err)
				continue
			}
			//优化时间
			loc, _ := time.LoadLocation("Local")
			tranTime, _ := time.ParseInLocation("20060102150405", result.TranTime, loc)
			if result.ResultFlag == lib.FUND_FLAG_suc {
				//代付成功后的逻辑操作
				if !result.GetFee().Equal(amountFee2) {
					paymentLog.Printf("查询代付手续费和实际代付手续费不一致:id:%v,resultfee:%v,fee:%v", id, result.GetFee(), amountFee2)
				}
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(list[busClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingSandpayModel.Field.F_status:      pay2.CLEAR_STATUS_suc,
					busClearingSandpayModel.Field.F_fee:         amountFee.String(),
					busClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					busClearingSandpayModel.Field.F_order_sn:    orderSn,
					busClearingSandpayModel.Field.F_agent_time:  tranTime.Local().Unix(),
				}); err != nil {
					paymentLog.Printf("updatedb for success err:id:%v,err:%v", id, err)
					continue
				}
				//更新商户单日资金归集表
				if _, err := busClearingModel.UpdateAgent(list[busClearingSandpayModel.Field.F_bus_id], list[busClearingSandpayModel.Field.F_id], order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("updatedb for busclearingmodel err:id:%v,err:%v", id, err)
					continue
				}
				//新增代付成功关联表
				insId := busClearingFundRealationModel.Insert(map[string]interface{}{
					busClearingFundRealationModel.Field.F_bus_id:            busId,
					busClearingFundRealationModel.Field.F_order_sn:          orderSn,
					busClearingFundRealationModel.Field.F_fund_channel_id:   id,
					busClearingFundRealationModel.Field.F_fund_channel_type: order.PAY_CHANNEL_sand,
					busClearingFundRealationModel.Field.F_create_time:       tranTime.Unix(),
				})
				if insId == 0 {
					paymentLog.Printf("insertdn err for busClearingFundRealationmodel err:id:%v", id)
					continue
				}
				//\\新增代付成功关联表

				//记账
				if err := rpcFund.PayCharge(ctx, &bus.FundRecord{
					BusId: busId,
					FundRecordList: []bus.FundRecordItem{
						{
							OrderSn:  orderSn,
							Amount:   list[busClearingSandpayModel.Field.F_depository_amount].(string),
							FundType: bus.FUND_TYPE_depository, //清分到存管
						}, {
							OrderSn:  orderSn,
							Amount:   usableAmount.String(),
							FundType: bus.FUND_TYPE_usable, //清分到可提现
						}, {
							OrderSn:  orderSn,
							Amount:   amountFee.String(),
							FundType: bus.FUND_TYPE_agent_fee_out, //清算手续费
						},
					},
				}, &reply); err != nil {
					paymentLog.Printf("handler busfundrecordmodel err:id:%v,err:%v", id, err)
					continue
				}
				//\\记账

				//添加出账中的任务
				busClearingList := busClearingModel.GetListByAgentIdAndAgentType(id, pay2.AGENT_TYPE_sand)
				if len(busClearingList) > 0 {
					for _, m := range busClearingList {
						clearId := m[busClearingModel.Field.F_id].(string)
						agentSucReply := false
						_ = taskPay.AgentSuc(ctx, &clearId, &agentSucReply)
					}
				}
				//\\添加出账中的任务

				//记录日志
				paymentLog.Printf("sandpay payment success:id:%v", id)
				//\\记录日志

			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				rest = false
				//有非及时结果,需异步处理
				//代付中
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(list[busClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingSandpayModel.Field.F_order_sn:    orderSn,
					busClearingSandpayModel.Field.F_fee:         amountFee.String(),
					busClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					busClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("清分结果为代付中:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment fail:id:%v,err:%v", id, "代付失败")
				//\\记录日志
				//代付失败
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(list[busClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingSandpayModel.Field.F_status:     pay2.CLEAR_STATUS_fail,
					busClearingSandpayModel.Field.F_fee:        amountFee.String(),
					busClearingSandpayModel.Field.F_error_msg:  "代付失败",
					busClearingSandpayModel.Field.F_order_sn:   orderSn,
					busClearingSandpayModel.Field.F_agent_time: tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror for sandpay fail err:id:%v,err:%v", id, err)
					continue
				}
				// 商户单日资金结算表
				if _, err := busClearingModel.UpdateAgent(list[busClearingSandpayModel.Field.F_bus_id], id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror for sandpay fail:id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付查询【商户】
 * @return void
 */
func (s *sandPay) FundAgentResult(ctx context.Context) (rest bool) {
	rest = true
	//实例化清分表
	//杉德代付表
	busClearingSandpayModel := new(models.BusClearingSandpayModel).Init()
	//商户清分表
	busClearingModel := new(models.BusClearingModel).Init(busClearingSandpayModel.Model.GetOrmer())
	//清分成功关联表
	busClearingFundRealationModel := new(models.BusClearingFundRealationModel).Init(busClearingSandpayModel.Model.GetOrmer())
	//定义商户资金存管账户信息
	reply := false
	rpcFund := new(bus2.Fund).Init()
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	taskPay := new(pay3.Pay).Init()
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForMerchantQuery"))
	for true {
		lists := busClearingSandpayModel.GetFundIngList(pay2.CLEAR_STATUS_ing, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		now := time.Now().Local()
		for _, list := range lists {
			//获取相关信息
			//商户ID
			busId, _ := strconv.Atoi(list[busClearingSandpayModel.Field.F_bus_id].(string))
			//待代付表ID
			id, _ := strconv.Atoi(list[busClearingSandpayModel.Field.F_id].(string))
			//查询时间
			agentTime, _ := strconv.Atoi(list[busClearingSandpayModel.Field.F_agent_time].(string))
			//转换查询时间
			tranTime := time.Unix(int64(agentTime), 0).Format("20060102150405")
			orderSn := list[busClearingSandpayModel.Field.F_order_sn].(string)
			if orderSn == "" {
				paymentLog.Printf("查询订单号为空:id:%v", id)
				continue
			}
			//查询代付结果
			result, err := lib.Sandpay.AgentQuery(orderSn, tranTime)
			if err != nil {
				paymentLog.Printf("杉德查询结果失败:id:%v,err:%v", id, err)
				continue
			}
			if result.ResultFlag == lib.FUND_FLAG_suc {
				//查询结果成功
				amountFee, _ := decimal.NewFromString(list[busClearingSandpayModel.Field.F_fee].(string))
				usableAmount, _ := decimal.NewFromString(list[busClearingSandpayModel.Field.F_usable_amount].(string))
				usableAmount = usableAmount.Sub(amountFee)
				//代付手续费验证
				if !result.GetFee().Equal(amountFee) {
					paymentLog.Printf("杉德查询手续费与实际代付手续费不一致:id:%v,resutfee:%v;fee:%v", id, result.GetFee(), amountFee)
				}
				// 代付成功
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(list[busClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingSandpayModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("updatedb for success err:id:%v,err:%v", id, err)
					continue
				}
				//商户单日资金归集表
				if _, err := busClearingModel.UpdateAgent(busId, id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("updatedb for busclearingmodel err:id:%v,err:%v", id, err)
					continue
				}
				insId := busClearingFundRealationModel.Insert(map[string]interface{}{
					busClearingFundRealationModel.Field.F_bus_id:            busId,
					busClearingFundRealationModel.Field.F_order_sn:          orderSn,
					busClearingFundRealationModel.Field.F_fund_channel_id:   id,
					busClearingFundRealationModel.Field.F_fund_channel_type: order.PAY_CHANNEL_sand,
					busClearingFundRealationModel.Field.F_create_time:       now.Unix(),
				})
				if insId == 0 {
					paymentLog.Printf("insertdn err for busClearingFundRealationmodel err:id:%v", id)
					continue
				}
				if err := rpcFund.PayCharge(ctx, &bus.FundRecord{
					BusId: busId,
					FundRecordList: []bus.FundRecordItem{
						{
							OrderSn:  orderSn,
							Amount:   list[busClearingSandpayModel.Field.F_depository_amount].(string),
							FundType: bus.FUND_TYPE_depository,
						}, {
							OrderSn:  orderSn,
							Amount:   usableAmount.String(),
							FundType: bus.FUND_TYPE_usable,
						}, {
							OrderSn:  orderSn,
							Amount:   amountFee.String(),
							FundType: bus.FUND_TYPE_agent_fee_out,
						},
					},
				}, &reply); err != nil {
					paymentLog.Printf("handler busfundrecordmodel err:id:%v,err:%v", id, err)
					continue
				}
				//添加出账中的任务
				busClearingList := busClearingModel.GetListByAgentIdAndAgentType(id, pay2.AGENT_TYPE_sand)
				if len(busClearingList) > 0 {
					for _, m := range busClearingList {
						clearId := m[busClearingModel.Field.F_id].(string)
						agentSucReply := false
						_ = taskPay.AgentSuc(ctx, &clearId, &agentSucReply)
					}
				}
				//\\添加出账中的任务

				//记录日志
				paymentLog.Printf("sandpay payment query success:id:%v", id)
				//\\记录日志

			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				//拥有未处理完数据
				rest = false
				//代付中
				queryCount, _ := strconv.Atoi(list[busClearingSandpayModel.Field.F_query_count].(string))
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingSandpayModel.Field.F_query_count: queryCount + 1,
				}); err != nil {
					paymentLog.Printf("清分结果为代付中:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment query fail:id:%v,err:%v", id, "查询代付失败")
				//\\记录日志
				//代付失败
				if _, err := busClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					busClearingSandpayModel.Field.F_error_msg: "查询代付失败",
				}); err != nil {
					paymentLog.Printf("dberror for sandpay fail err:id:%v,err:%v", id, err)
					continue
				}
				// 商户单日资金结算表
				if _, err := busClearingModel.UpdateAgent(busId, id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					busClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror for sandpay fail:id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付资金【平台】
 * @return void
 */
func (s *sandPay) PlatFundAgent(ctx context.Context) (rest bool) {
	rest = true
	//如果是节假日，则不进行代付
	if !s.checkHolidayPayment() {
		return
	}
	platClearingSandpayModel := new(models.PlatformClearingSandpayModel).Init()
	platClearingModel := new(models.PlatformClearingModel).Init(platClearingSandpayModel.Model.GetOrmer())
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForPlat"))
	platAcct := new(PlatAcct).GetInstance()
	for true {
		lists := platClearingSandpayModel.GetListsByStatus(pay2.CLEAR_STATUS_none, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		for _, list := range lists {
			orderSn := "PP" + strconv.FormatInt(lib.Worker.GetId(), 10)
			id, _ := strconv.Atoi(list[platClearingSandpayModel.Field.F_id].(string))
			amount, _ := decimal.NewFromString(list[platClearingSandpayModel.Field.F_amount].(string))
			//获取计算手续费
			fee, err := lib.Sandpay.AgentFee(orderSn, amount, platAcct.GetAcctNo())
			if err != nil {
				paymentLog.Printf("计算手续费错误:err:%v", err)
				continue
			}
			amountFee := fee.GetFee()
			//\\获取计算手续费
			fundAmount := amount.Sub(amountFee)
			if fundAmount.Cmp(decimal.NewFromInt(0)) != 1 {
				paymentLog.Printf("平台手续费代付金额小于代付手续费")
				continue
			}
			//修改清分表状态
			if _, err := platClearingSandpayModel.UpdateAgent(id, pay2.CLEAR_STATUS_none, amount.String(), map[string]interface{}{
				platClearingSandpayModel.Field.F_status:         pay2.CLEAR_STATUS_ing,
				platClearingSandpayModel.Field.F_card_name:      platAcct.GetAcctName(),
				platClearingSandpayModel.Field.F_card_no:        platAcct.GetAcctNo(),
				platClearingSandpayModel.Field.F_card_bank_name: platAcct.GetAcctBranch(),
				platClearingSandpayModel.Field.F_card_bank_no:   platAcct.GetAcctBankNo(),
			}); err != nil {
				paymentLog.Printf("dberr for platClearingSandpayModel ing id:%v,err:%v", id, err)
				continue
			}
			orderSn = "PY" + strconv.FormatInt(lib.Worker.GetId(), 10)
			//执行代付
			result, err := lib.Sandpay.AgentPay(orderSn, fundAmount, platAcct.GetAcctNo(), platAcct.GetAcctName(), platAcct.GetAcctBranch(), platAcct.GetAcctBankNo())
			if err != nil {
				paymentLog.Printf("执行杉德代付操作失败:id:%v,err:%v", id, err)
				continue
			}
			loc, _ := time.LoadLocation("Local")
			tranTime, _ := time.ParseInLocation("20060102150405", result.TranTime, loc)
			if result.ResultFlag == lib.FUND_FLAG_suc {
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					paymentLog.Printf("查询手续费与实际代付手续费不一致:id:%v,resutfee:%v;fee:%v", id, resFee, amountFee)
				}
				//代付成功
				if _, err := platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingSandpayModel.Field.F_status:      pay2.CLEAR_STATUS_suc,
					platClearingSandpayModel.Field.F_fee:         resFee.String(),
					platClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					platClearingSandpayModel.Field.F_order_sn:    orderSn,
					platClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror platClearingSandpayModel success:id:%v,err:%v", id, err)
					continue
				}
				//保险公司单日资金结算表
				if _, err := platClearingModel.UpdateAgent(id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("dberror platClearingModel success:id:%v,err:%v", id, err)
					continue
				}
				//记录日志
				paymentLog.Printf("sandpay payment success:id:%v", id)
				//\\记录日志

			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				// 有非及时结果，需异步处理
				rest = false
				//代付中
				if _, err := platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingSandpayModel.Field.F_order_sn:    orderSn,
					platClearingSandpayModel.Field.F_fee:         amountFee.String(),
					platClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					platClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror platClearingSandpayModel paying:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment fail:id:%v,err:%v", id, "代付失败")
				//\\记录日志
				//代付失败
				if _, err := platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingSandpayModel.Field.F_status:     pay2.CLEAR_STATUS_fail,
					platClearingSandpayModel.Field.F_fee:        amountFee.String(),
					platClearingSandpayModel.Field.F_error_msg:  "代付失败",
					platClearingSandpayModel.Field.F_order_sn:   orderSn,
					platClearingSandpayModel.Field.F_agent_time: tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror platClearingSandpayModel fail:id:%v,err:%v", id, err)
					continue
				}
				// 商户单日资金结算表
				if _, err := platClearingModel.UpdateAgent(id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror platClearingModel fail :id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付查询【平台】
 * @return void
 */
func (s *sandPay) PlatFundAgentResult(ctx context.Context) (rest bool) {
	rest = true
	platClearingSandpayModel := new(models.PlatformClearingSandpayModel).Init()
	platClearingModel := new(models.PlatformClearingModel).Init(platClearingSandpayModel.Model.GetOrmer())
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForPlatQuery"))
	for true {
		lists := platClearingSandpayModel.GetListsByStatus(pay2.CLEAR_STATUS_ing, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		for _, list := range lists {
			id, _ := strconv.Atoi(list[platClearingSandpayModel.Field.F_id].(string))
			agentTime, _ := strconv.Atoi(list[platClearingSandpayModel.Field.F_agent_time].(string))
			tranTime := time.Unix(int64(agentTime), 0).Format("20060102150405")
			orderSn := list[platClearingSandpayModel.Field.F_order_sn].(string)
			if orderSn == "" {
				paymentLog.Printf("查询订单号为空:id:%v", id)
				continue
			}
			//代付结果查询
			result, err := lib.Sandpay.AgentQuery(orderSn, tranTime)
			if err != nil {
				paymentLog.Printf("杉德查询结果失败:id:%v,err:%v", id, err)
				continue
			}
			if result.ResultFlag == lib.FUND_FLAG_suc {
				//查询成功
				amountFee, _ := decimal.NewFromString(list[platClearingSandpayModel.Field.F_fee].(string))
				upData := map[string]interface{}{
					platClearingSandpayModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}
				//手续费判断
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					//手续费处理
					upData[platClearingSandpayModel.Field.F_fee] = resFee.String()
					paymentLog.Printf("查询手续费与实际代付手续费不一致:id:%v,resutfee:%v,fee:%v", id, resFee, amountFee)
				}
				//更新
				if _, err := platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, upData); err != nil {
					paymentLog.Printf("dberror platClearingSandpayModel success:id:%v,err:%v", id, err)
					continue
				}
				// 保险公司单日资金结算表
				if upRes, err := platClearingModel.UpdateAgent(id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil || upRes == 0 {
					paymentLog.Printf("dberror platClearingModel success:id:%v,err:%v", id, err)
					continue
				}
				//记录日志
				paymentLog.Printf("sandpay payment query success:id:%v", id)
				//\\记录日志
			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				//拥有未处理完数据
				rest = false
				//代付中
				queryCount, _ := strconv.Atoi(list[platClearingSandpayModel.Field.F_query_count].(string))
				if _, err := platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingSandpayModel.Field.F_query_count: queryCount + 1,
				}); err != nil {
					paymentLog.Printf("dberror platClearingSandpayModel pay no result:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment query fail:id:%v,err:%v", id, "查询代付失败")
				//\\记录日志
				//代付失败
				if _, err := platClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					platClearingSandpayModel.Field.F_error_msg: "查询代付失败",
				}); err != nil {
					paymentLog.Printf("dberror platClearingSandpayModel fail:id:%v,err:%v", id, err)
					continue
				}
				// 商户单日资金结算表
				if _, err := platClearingModel.UpdateAgent(id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					platClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror platClearingModel fail :id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付资金【保险公司】
 * @return void
 */
func (s *sandPay) InsureFundAgent(ctx context.Context) (rest bool) {
	rest = true
	//如果是节假日，则不进行代付
	if !s.checkHolidayPayment() {
		return
	}
	insureClearingSandpayModel := new(models.InsureClearingSandpayModel).Init()
	insureClearingModel := new(models.InsureClearingModel).Init(insureClearingSandpayModel.Model.GetOrmer())
	insureSandpayModel := new(models.InsureSandpayModel).Init(insureClearingSandpayModel.Model.GetOrmer())
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForInsure"))
	for true {
		lists := insureClearingSandpayModel.GetListsByStatus(pay2.CLEAR_STATUS_none, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		//查询保险公司账户信息
		insureIds := functions.ArrayValue2Array(insureClearingSandpayModel.Field.F_insure_id, lists)
		replyDeposSandInfos := insureSandpayModel.GetListByInsureIds(insureIds)
		if len(replyDeposSandInfos) == 0 {
			paymentLog.Printf("保险公司收款账户信息获取失败,insureIds:%v", insureIds)
			return
		}
		//\\查询保险公司账户信息

		//获取保险公司账户信息
		res := functions.ArrayRebuild(insureSandpayModel.Field.F_insure_id, replyDeposSandInfos)
		for _, list := range lists {
			insureId := list[insureClearingSandpayModel.Field.F_insure_id].(string)
			id, _ := strconv.Atoi(list[insureClearingSandpayModel.Field.F_id].(string))
			// 获取保险公司账户信息
			sandInfos, ok := res[insureId]
			if !ok {
				utils.Logerr.Printf("保险公司收款账户未查询到:insure_id:%v", insureId)
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_none, map[string]interface{}{
					insureClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					insureClearingSandpayModel.Field.F_error_msg: "保险公司收款账户未查询到",
				}); err != nil {
					paymentLog.Printf("dberr for insureClearingSandpayModel update insure_id:%v, clearingSandpayId:%v", insureId, id)
					continue
				}
				continue
			}
			sandInfo := sandInfos.(map[string]interface{})
			orderSn := "PI" + strconv.FormatInt(lib.Worker.GetId(), 10)
			amount, _ := decimal.NewFromString(list[insureClearingSandpayModel.Field.F_amount].(string))
			//获取计算手续费
			fee, err := lib.Sandpay.AgentFee(orderSn, amount, sandInfo[insureSandpayModel.Field.F_acct_no].(string))
			if err != nil {
				paymentLog.Printf("计算手续费错误:err:%v", err)
				continue
			}
			amountFee := fee.GetFee()
			//\\获取计算手续费
			fundAmount := amount.Sub(amountFee)
			if fundAmount.Cmp(decimal.NewFromInt(0)) != 1 {
				paymentLog.Printf("保费代付金额小于代付手续费")
				continue
			}
			//修改清分表状态
			if _, err := insureClearingSandpayModel.UpdateAgent(list[insureClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_none, amount.String(), map[string]interface{}{
				insureClearingSandpayModel.Field.F_status:         pay2.CLEAR_STATUS_ing,
				insureClearingSandpayModel.Field.F_card_name:      sandInfo[insureSandpayModel.Field.F_acct_name],
				insureClearingSandpayModel.Field.F_card_no:        sandInfo[insureSandpayModel.Field.F_acct_no],
				insureClearingSandpayModel.Field.F_card_bank_name: sandInfo[insureSandpayModel.Field.F_bank_name],
				insureClearingSandpayModel.Field.F_card_bank_no:   sandInfo[insureSandpayModel.Field.F_bank_no],
			}); err != nil {
				paymentLog.Printf("dberr for insureClearingSandpayModel ing id:%v,err:%v", id, err)
				continue
			}
			orderSn = "PZ" + strconv.FormatInt(lib.Worker.GetId(), 10)
			//执行代付
			result, err := lib.Sandpay.AgentPay(orderSn, fundAmount, sandInfo[insureSandpayModel.Field.F_acct_no].(string), sandInfo[insureSandpayModel.Field.F_acct_name].(string), sandInfo[insureSandpayModel.Field.F_bank_name].(string), sandInfo[insureSandpayModel.Field.F_bank_no].(string))
			if err != nil {
				paymentLog.Printf("执行杉德代付操作失败:id:%v,err:%v", id, err)
				continue
			}
			loc, _ := time.LoadLocation("Local")
			tranTime, _ := time.ParseInLocation("20060102150405", result.TranTime, loc)
			if result.ResultFlag == lib.FUND_FLAG_suc {
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					paymentLog.Printf("查询手续费与实际代付手续费不一致:id:%v,resutfee:%v;fee:%v", id, resFee, amountFee)
				}
				//代付成功
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(list[insureClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingSandpayModel.Field.F_status:      pay2.CLEAR_STATUS_suc,
					insureClearingSandpayModel.Field.F_fee:         resFee.String(),
					insureClearingSandpayModel.Field.F_order_sn:    orderSn,
					insureClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					insureClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror insureClearingSandpayModel success:id:%v,err:%v", id, err)
					continue
				}
				//保险公司单日资金结算表
				if _, err := insureClearingModel.UpdateAgent(insureId, id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("dberror insureClearingModel success:id:%v,err:%v", id, err)
					continue
				}
				//记录日志
				paymentLog.Printf("sandpay payment success:id:%v", id)
				//\\记录日志
			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				// 有非及时结果，需异步处理
				rest = false
				//代付中
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingSandpayModel.Field.F_order_sn:    orderSn,
					insureClearingSandpayModel.Field.F_fee:         amountFee.String(),
					insureClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					insureClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror insureClearingSandpayModel paying:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment  fail:id:%v,err:%v", id, "代付失败")
				//\\记录日志
				//代付失败
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingSandpayModel.Field.F_status:     pay2.CLEAR_STATUS_fail,
					insureClearingSandpayModel.Field.F_fee:        amountFee.String(),
					insureClearingSandpayModel.Field.F_error_msg:  "代付失败",
					insureClearingSandpayModel.Field.F_order_sn:   orderSn,
					insureClearingSandpayModel.Field.F_agent_time: tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror insureClearingSandpayModel fail:id:%v,err:%v", id, err)
					continue
				}
				// 商户单日资金结算表
				if _, err := insureClearingModel.UpdateAgent(insureId, id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror insureClearingModel fail :id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付查询【保险公司】
 * @return void
 */
func (s *sandPay) InsureFundAgentResult(ctx context.Context) (rest bool) {
	rest = true
	insureClearingSandpayModel := new(models.InsureClearingSandpayModel).Init()
	insureClearingModel := new(models.InsureClearingModel).Init(insureClearingSandpayModel.Model.GetOrmer())
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForInsureQuery"))
	for true {
		lists := insureClearingSandpayModel.GetFundIngList(pay2.CLEAR_STATUS_ing, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		for _, list := range lists {
			id, _ := strconv.Atoi(list[insureClearingSandpayModel.Field.F_id].(string))
			agentTime, _ := strconv.Atoi(list[insureClearingSandpayModel.Field.F_agent_time].(string))
			tranTime := time.Unix(int64(agentTime), 0).Format("20060102150405")
			orderSn := list[insureClearingSandpayModel.Field.F_order_sn].(string)
			if orderSn == "" {
				paymentLog.Printf("查询订单号为空:id:%v", id)
				continue
			}
			//代付结果查询
			result, err := lib.Sandpay.AgentQuery(orderSn, tranTime)
			if err != nil {
				paymentLog.Printf("杉德查询结果失败:id:%v,err:%v", id, err)
				continue
			}
			if result.ResultFlag == lib.FUND_FLAG_suc {
				//查询成功
				amountFee, _ := decimal.NewFromString(list[insureClearingSandpayModel.Field.F_fee].(string))
				upData := map[string]interface{}{
					insureClearingSandpayModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}
				//手续费判断
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					//手续费处理
					upData[insureClearingSandpayModel.Field.F_fee] = resFee.String()
					paymentLog.Printf("查询手续费与实际代付手续费不一致:id:%v,resutfee:%v,fee:%v", id, resFee, amountFee)
				}
				//更新
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, upData); err != nil {
					utils.Logerr.Printf("dberror insureClearingSandpayModel success:id:%v,err:%v", id, err)
					continue
				}
				// 保险公司单日资金结算表
				if _, err := insureClearingModel.UpdateAgent(list[insureClearingSandpayModel.Field.F_insure_id], list[insureClearingSandpayModel.Field.F_id], order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("dberror insureClearingModel success:id:%v,err:%v", id, err)
					continue
				}
				//记录日志
				paymentLog.Printf("sandpay payment query success:id:%v", id)
				//\\记录日志

			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				//拥有未处理完数据
				rest = false
				//代付中
				queryCount, _ := strconv.Atoi(list[insureClearingSandpayModel.Field.F_query_count].(string))
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingSandpayModel.Field.F_query_count: queryCount + 1,
				}); err != nil {
					paymentLog.Printf("dberror insureClearingSandpayModel pay no result:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment query fail:id:%v,err:%v", id, "查询代付失败")
				//\\记录日志
				//代付失败
				if _, err := insureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					insureClearingSandpayModel.Field.F_error_msg: "查询代付失败",
				}); err != nil {
					paymentLog.Printf("dberror insureClearingSandpayModel fail:id:%v,err:%v", id, err)
					continue
				}
				// 商户单日资金结算表
				if _, err := insureClearingModel.UpdateAgent(list[insureClearingSandpayModel.Field.F_insure_id], id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					insureClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror insureClearingModel fail :id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付资金【保险公司-续保保费】
 * @return void
 */
func (s *sandPay) RenewInsureFundAgent(ctx context.Context) (rest bool) {
	rest = true
	//如果是节假日，则不进行代付
	if !s.checkHolidayPayment() {
		return
	}
	renewInsureClearingSandpayModel := new(models.RenewInsureClearingSandpayModel).Init()
	renewInsureClearingModel := new(models.RenewInsureClearingModel).Init(renewInsureClearingSandpayModel.Model.GetOrmer())
	renewInsureSandpayModel := new(models.RenewInsureSandpayModel).Init(renewInsureClearingSandpayModel.Model.GetOrmer())
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForRenewInsure"))
	for true {
		lists := renewInsureClearingSandpayModel.GetListsByStatus(pay2.CLEAR_STATUS_none, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		//获取保险保险公司账户信息
		insureIds := functions.ArrayValue2Array(renewInsureClearingSandpayModel.Field.F_renew_insure_id, lists)
		replyDeposSandInfos := renewInsureSandpayModel.GetListByInsureIds(insureIds)
		if len(replyDeposSandInfos) == 0 {
			paymentLog.Printf("续保保险公司收款账户信息获取失败,insureIds:%v", insureIds)
			return
		}
		//\\获取保险保险公司账户信息
		res := functions.ArrayRebuild(renewInsureSandpayModel.Field.F_renew_insure_id, replyDeposSandInfos)
		for _, list := range lists {
			insureId := list[renewInsureClearingSandpayModel.Field.F_renew_insure_id].(string)
			id, _ := strconv.Atoi(list[renewInsureClearingSandpayModel.Field.F_id].(string))
			// 获取保险公司账户信息
			sandInfos, ok := res[insureId]
			if !ok {
				utils.Logerr.Printf("续保保险公司账户信息未查到:insure_id:%v", insureId)
				if _, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_none, map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					renewInsureClearingSandpayModel.Field.F_error_msg: "未找到续保公司存管账户信息",
				}); err != nil {
					paymentLog.Printf("dberror update fail for renewInsureClearingSandpayModel insure_id:%v,clearingSandpayId:%v", insureId, id)
					continue
				}
				continue
			}
			sandInfo := sandInfos.(map[string]interface{})
			orderSn := "PR" + strconv.FormatInt(lib.Worker.GetId(), 10)
			amount, _ := decimal.NewFromString(list[renewInsureClearingSandpayModel.Field.F_amount].(string))
			// 获取计算手续费
			fee, err := lib.Sandpay.AgentFee(orderSn, amount, sandInfo[renewInsureSandpayModel.Field.F_acct_no].(string))
			if err != nil {
				paymentLog.Printf("计算手续费错误:err:%v", err)
				continue
			}
			amountFee := fee.GetFee()
			//\\ 获取计算手续费

			fundAmount := amount.Sub(amountFee)
			if fundAmount.Cmp(decimal.NewFromInt(0)) != 1 {
				paymentLog.Printf("续保保费代付金额小于代付手续费")
				continue
			}
			if _, err := renewInsureClearingSandpayModel.UpdateAgent(id, pay2.CLEAR_STATUS_none, amount.String(), map[string]interface{}{
				renewInsureClearingSandpayModel.Field.F_status:         pay2.CLEAR_STATUS_ing,
				renewInsureClearingSandpayModel.Field.F_card_name:      sandInfo[renewInsureSandpayModel.Field.F_acct_name],
				renewInsureClearingSandpayModel.Field.F_card_no:        sandInfo[renewInsureSandpayModel.Field.F_acct_no],
				renewInsureClearingSandpayModel.Field.F_card_bank_name: sandInfo[renewInsureSandpayModel.Field.F_bank_name],
				renewInsureClearingSandpayModel.Field.F_card_bank_no:   sandInfo[renewInsureSandpayModel.Field.F_bank_no],
			}); err != nil {
				paymentLog.Printf("dberror update ing:id:%v,err:%v", id, err)
				continue
			}
			orderSn = "PR" + strconv.FormatInt(lib.Worker.GetId(), 10)
			// 执行代付
			result, err := lib.Sandpay.AgentPay(orderSn, fundAmount, sandInfo[renewInsureSandpayModel.Field.F_acct_no].(string), sandInfo[renewInsureSandpayModel.Field.F_acct_name].(string), sandInfo[renewInsureSandpayModel.Field.F_bank_name].(string), sandInfo[renewInsureSandpayModel.Field.F_bank_no].(string))
			if err != nil {
				paymentLog.Printf("执行杉德代付操作失败:id:%v,err:%v", id, err)
				continue
			}
			loc, _ := time.LoadLocation("Local")
			tranTime, _ := time.ParseInLocation("20060102150405", result.TranTime, loc)
			if result.ResultFlag == lib.FUND_FLAG_suc {
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					paymentLog.Printf("查询手续费与实际代付手续费不一致:id:%v；resutfee:%v;fee:%v", list[renewInsureClearingSandpayModel.Field.F_id], resFee, amountFee)
				}
				// 代付成功
				if upRes, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(list[renewInsureClearingSandpayModel.Field.F_id], pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_status:      pay2.CLEAR_STATUS_suc,
					renewInsureClearingSandpayModel.Field.F_fee:         resFee.String(),
					renewInsureClearingSandpayModel.Field.F_order_sn:    orderSn,
					renewInsureClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					renewInsureClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil || upRes == 0 {
					paymentLog.Printf("dberror update success renewInsureClearingSandpayModel id:%v,err:%v", id, err)
					continue
				}
				//续保单日资金结算表
				if _, err := renewInsureClearingModel.UpdateAgent(list[renewInsureClearingSandpayModel.Field.F_renew_insure_id], list[renewInsureClearingSandpayModel.Field.F_id], order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("dberror update success renewInsureClearingModel id:%v,err:%v", id, err)
					continue
				}
				//记录日志
				paymentLog.Printf("sandpay payment success:id:%v", id)
				//\\记录日志
			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				// 有非及时结果，需异步处理
				rest = false
				// 代付中
				if _, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_order_sn:    orderSn,
					renewInsureClearingSandpayModel.Field.F_fee:         amountFee.String(),
					renewInsureClearingSandpayModel.Field.F_real_amount: fundAmount.String(),
					renewInsureClearingSandpayModel.Field.F_agent_time:  tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror renewInsureClearingSandpayModel paying:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment fail:id:%v,err:%v", id, "代付失败")
				//\\记录日志
				//代付失败
				if _, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_status:     pay2.CLEAR_STATUS_fail,
					renewInsureClearingSandpayModel.Field.F_fee:        amountFee.String(),
					renewInsureClearingSandpayModel.Field.F_error_msg:  "代付失败",
					renewInsureClearingSandpayModel.Field.F_order_sn:   orderSn,
					renewInsureClearingSandpayModel.Field.F_agent_time: tranTime.Unix(),
				}); err != nil {
					paymentLog.Printf("dberror fail for renewInsureClearingSandpayModel id:%v,err:%v", id, err)
					continue
				}
				//续保保费单日资金结算表
				if _, err := renewInsureClearingModel.UpdateAgent(list[renewInsureClearingSandpayModel.Field.F_renew_insure_id], id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror fail for renewInsureClearingModel id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付查询【保险公司-续保】
 * @return void
 */
func (s *sandPay) RenewInsureFundAgentResult(ctx context.Context) (rest bool) {
	rest = true
	renewInsureClearingSandpayModel := new(models.RenewInsureClearingSandpayModel).Init()
	renewInsureClearingModel := new(models.RenewInsureClearingModel).Init(renewInsureClearingSandpayModel.Model.GetOrmer())
	//定义获取待代付起始数据
	start := 0
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForRenewInsureQuery"))
	for true {
		lists := renewInsureClearingSandpayModel.GetFundIngList(pay2.CLEAR_STATUS_ing, start, linCount)
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		for _, list := range lists {
			insureId, _ := strconv.Atoi(list[renewInsureClearingSandpayModel.Field.F_renew_insure_id].(string))
			id, _ := strconv.Atoi(list[renewInsureClearingSandpayModel.Field.F_id].(string))
			agentTime, _ := strconv.Atoi(list[renewInsureClearingSandpayModel.Field.F_agent_time].(string))
			tranTime := time.Unix(int64(agentTime), 0).Format("20060102150405")
			orderSn := list[renewInsureClearingSandpayModel.Field.F_order_sn].(string)
			if orderSn == "" {
				paymentLog.Printf("查询订单号为空:id:%v", id)
				continue
			}
			// 代付结果查询
			result, err := lib.Sandpay.AgentQuery(orderSn, tranTime)
			if err != nil {
				paymentLog.Printf("杉德查询结果失败:id:%v,err:%v", id, err)
				continue
			}
			if result.ResultFlag == lib.FUND_FLAG_suc {
				amountFee, _ := decimal.NewFromString(list[renewInsureClearingSandpayModel.Field.F_fee].(string))
				// 手续费判断
				upData := map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					// 手续费处理
					upData[renewInsureClearingSandpayModel.Field.F_fee] = resFee.String()
					utils.Logerr.Printf("查询手续费与实际代付手续费不一致:id:%v,resutfee:%v;fee:%v", id, resFee, amountFee)
				}
				//代付成功
				if _, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, upData); err != nil {
					paymentLog.Printf("dberror update success insureClearingSandpayModel id:%v,err:%v", id, err)
					continue
				}
				// 保险公司单日资金结算表
				if _, err := renewInsureClearingModel.UpdateAgent(insureId, id, order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingModel.Field.F_status: pay2.CLEAR_STATUS_suc,
				}); err != nil {
					paymentLog.Printf("dberror update success renewInsureClearingModel id:%v,err:%v", id, err)
					continue
				}
				//记录日志
				paymentLog.Printf("sandpay payment query success:id:%v", id)
				//\\记录日志
			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				// 拥有未处理完数据
				rest = false
				// 代付中
				queryCount, _ := strconv.Atoi(list[renewInsureClearingSandpayModel.Field.F_query_count].(string))
				if _, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_query_count: queryCount + 1,
				}); err != nil {
					paymentLog.Printf("dberror renewInsureClearingSandpayModel paying:id:%v,err:%v", id, err)
					continue
				}
			} else {
				//记录日志
				paymentLog.Printf("sandpay payment query fail:id:%v,err:%v", id, "查询代付失败")
				//\\记录日志
				// 代付失败
				if _, err := renewInsureClearingSandpayModel.UpdateByIdAndStatus(id, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingSandpayModel.Field.F_status:    pay2.CLEAR_STATUS_fail,
					renewInsureClearingSandpayModel.Field.F_error_msg: "查询代付失败",
				}); err != nil {
					paymentLog.Printf("dberror fail for renewInsureClearingSandpayModel id:%v,err:%v", id, err)
					continue
				}
				//保险公司单日资金结算表
				if _, err := renewInsureClearingModel.UpdateAgent(list[renewInsureClearingSandpayModel.Field.F_renew_insure_id], list[renewInsureClearingSandpayModel.Field.F_id], order.PAY_CHANNEL_sand, pay2.CLEAR_STATUS_ing, map[string]interface{}{
					renewInsureClearingModel.Field.F_status: pay2.CLEAR_STATUS_fail,
				}); err != nil {
					paymentLog.Printf("dberror fail for renewInsureClearingModel id:%v,err:%v", id, err)
					continue
				}
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付资金【共享卡】
 * @return void
 */
func (s *sandPay) ShareCardFundAgent(ctx context.Context) (rest bool) {
	rest = true
	//如果是节假日，则不进行代付
	if !s.checkHolidayPayment() {
		return
	}
	//共享卡提现
	rpcShare := new(market.Share).Init()
	defer rpcShare.Close()
	//定义获取待代付起始数据
	start := 1
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForShareCard"))
	for true {
		//查询所有待提现的数据
		var rpcShareRes market2.ReplyGetAllWithdrawingInfo
		if err := rpcShare.GetAllWithdrawingInfoRpc(ctx, &market2.ArgsGetAllWithdrawingInfo{
			Paging: common.Paging{Page: start, PageSize: linCount},
			Status: market2.WITHDRAW_STATUS_WAIT,
		}, &rpcShareRes); err != nil {
			paymentLog.Printf("ShareCardFundAgent GetAllWithdrawingInfoRpc error:%s\n", err.Error())
			continue
		}

		lists := rpcShareRes.Lists
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		for _, list := range lists {
			orderSn, cardName, cardNumber, bankCode, bankName, cashAmount := list.OrderSn, list.CardName, list.CardNumber, list.BankCode, list.BankName, list.CashAmount
			amount := decimal.NewFromFloat(cashAmount)
			//获取计算手续费
			orderSnTem := "PSC" + strconv.FormatInt(lib.Worker.GetId(), 10)
			fee, err := lib.Sandpay.AgentFee(orderSnTem, amount, cardNumber)
			if err != nil {
				paymentLog.Printf("共享卡代付 计算手续费错误:err:%v", err)
				continue
			}
			amountFee := fee.GetFee() //提现手续费
			//实际代付金额=原金额-提现手续费
			fundAmount := amount.Sub(amountFee)
			//如果提现手续费大于总金额则跳出，继续
			if amount.Cmp(amountFee) < 0 {
				paymentLog.Printf("共享卡代付 提现手续费大于代付金额， 手续费：%v, 代付金额：%v", amountFee, amount)
				continue
			}
			//执行代付
			cspOrderSn := "PSD" + strconv.FormatInt(lib.Worker.GetId(), 10)
			result, err := lib.Sandpay.AgentPay(cspOrderSn, fundAmount, cardNumber, cardName, bankName, bankCode)
			if err != nil {
				paymentLog.Printf("执行共享卡杉德代付操作失败:cspOrderSn:%v,err:%v", cspOrderSn, err)
				continue
			}
			loc, _ := time.LoadLocation("Local")
			tranTime, _ := time.ParseInLocation("20060102150405", result.TranTime, loc)
			cashFee, _ := amountFee.Float64()
			shareCardUpdateData := &market2.ArgsUpdateShareCardWithdrawByOrderSn{
				OrderSn: orderSn, CashFee: cashFee, AgentTime: tranTime.Unix(),
				CspOrderSn: cspOrderSn,
			}

			if result.ResultFlag == lib.FUND_FLAG_suc {
				resFee := result.GetFee()
				if !resFee.Equal(amountFee) {
					paymentLog.Printf("共享卡代付 查询手续费与实际代付手续费不一致:orderSn:%v,resutfee:%v;fee:%v", orderSn, resFee, amountFee)
				}
				shareCardUpdateData.Status = market2.WITHDRAW_STATUS_SUCC
				//记录日志
				paymentLog.Printf("ShareCardFundAgent sandpay payment success:orderSn:%v", orderSn)

			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				// 有非及时结果，需异步处理
				rest = false
				shareCardUpdateData.Status = market2.WITHDRAW_STATUS_ING
			} else {
				//代付失败
				shareCardUpdateData.Status = market2.WITHDRAW_STATUS_FAIL
				shareCardUpdateData.ErrMsg = result.GetRespDesc()
				//记录日志
				paymentLog.Printf("ShareCardFundAgent sandpay payment fail:orderSn:%v,err:%v", orderSn, "代付失败")
			}
			//更新共享卡提现记录
			var rpcShareRes2 bool
			if err = rpcShare.UpdateShareCardWithdrawByOrderSnRpc(ctx, shareCardUpdateData, &rpcShareRes2); err != nil {
				paymentLog.Printf("ShareCardFundAgent UpdateShareCardWithdrawByOrderSnRpc error:%s\n", err.Error())
				continue
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 杉德代付查询【共享卡】
 * @return void
 */
func (s *sandPay) ShareCardFundAgentResult(ctx context.Context) (rest bool) {
	rest = true
	//共享卡提现
	rpcShare := new(market.Share).Init()
	defer rpcShare.Close()
	//定义获取待代付起始数据
	start := 1
	//每次获取50条杉德待代付数据
	linCount := 50
	//记录日志
	paymentLog := new(PaymentLog).GetInstance(kcgin.AppConfig.String("sandpay.agentForShareCardQuery"))
	for true {
		//查询所有提现中的数据
		var rpcShareRes market2.ReplyGetAllWithdrawingInfo
		if err := rpcShare.GetAllWithdrawingInfoRpc(ctx, &market2.ArgsGetAllWithdrawingInfo{
			Paging: common.Paging{Page: start, PageSize: linCount},
			Status: market2.WITHDRAW_STATUS_ING,
		}, &rpcShareRes); err != nil {
			paymentLog.Printf("ShareCardFundAgentResult GetAllWithdrawingInfoRpc error:%s\n", err.Error())
			continue
		}

		lists := rpcShareRes.Lists
		listsLen := len(lists)
		if listsLen == 0 {
			break
		}
		for _, list := range lists {
			//获取相关信息
			//查询时间
			agentTime := list.AgentTime
			//转换查询时间
			tranTime := time.Unix(agentTime, 0).Format("20060102150405")
			//订单编号
			orderSn := list.OrderSn
			if orderSn == "" {
				paymentLog.Printf("共享卡代付查询 查询订单号为空:orderSn:%v", orderSn)
				continue
			}
			//查询代付结果
			result, err := lib.Sandpay.AgentQuery(orderSn, tranTime)
			if err != nil {
				paymentLog.Printf("共享卡代付查询 杉德查询结果失败:orderSn:%v,err:%v", orderSn, err)
				continue
			}
			shareCardUpdateData := &market2.ArgsUpdateShareCardWithdrawByOrderSn{
				OrderSn: orderSn, CashFee: list.CashFee,
			}
			cashFee := decimal.NewFromFloat(list.CashFee)
			if result.ResultFlag == lib.FUND_FLAG_suc {
				//查询结果成功
				resFee := result.GetFee()
				if !resFee.Equal(cashFee) {
					paymentLog.Printf("共享卡代付查询 查询手续费与实际代付手续费不一致:orderSn:%v,resutfee:%v;fee:%v", orderSn, resFee, list.CashFee)
				}
				shareCardUpdateData.Status = market2.WITHDRAW_STATUS_SUCC
				//记录日志
				paymentLog.Printf("ShareCardFundAgentResult sandpay payment query success:orderSn:%v", orderSn)
			} else if result.ResultFlag == lib.FUND_FLAG_ing {
				//代付中
				//拥有未处理完数据
				rest = false
				//记录日志
				paymentLog.Printf("共享卡代付查询 清分结果为代付中:orderSn:%v,err:%v", orderSn, err)
			} else {
				//代付失败
				shareCardUpdateData.Status = market2.WITHDRAW_STATUS_FAIL
				shareCardUpdateData.ErrMsg = "查询代付失败"
				//记录日志
				paymentLog.Printf("ShareCardFundAgentResult sandpay payment query fail:orderSn:%v,err:%v", orderSn, "查询代付失败")
			}
			//更新共享卡提现记录
			var rpcShareRes2 bool
			if err = rpcShare.UpdateShareCardWithdrawByOrderSnRpc(ctx, shareCardUpdateData, &rpcShareRes2); err != nil {
				paymentLog.Printf("ShareCardFundAgentResult UpdateShareCardWithdrawByOrderSnRpc error:%s\n", err.Error())
				continue
			}
		}
		if listsLen != linCount {
			break
		}
	}
	return
}

/**
 * 验证如果是节假日则不进行代付
 * @return bool
 */
func (s *sandPay) checkHolidayPayment() (reply bool) {
	now := time.Now().Local()
	weekDay := int(now.Weekday())
	holidayModel := new(models.HolidayModel).Init()
	dateYmd, _ := strconv.ParseInt(time.Unix(now.Unix(), 0).Format("20060102"), 0, 64)
	if weekDay == 0 || weekDay == 6 {
		hasDay := holidayModel.GetByDateYmd(int(dateYmd))
		if len(hasDay) == 0 {
			reply = false
			return
		}
	} else {
		hasDay := holidayModel.GetByDateYmd(int(dateYmd))
		if len(hasDay) > 0 {
			reply = false
			return
		}
	}
	reply = true
	return
}

//获取保险资金结果
func (s *sandPay) GetInsureFund() bool {
	return true
}
